//
// Created by limo on 2025/9/26.
//

#pragma once

#include <memory>
#include <functional>
#include <string>
#include <boost/asio.hpp>
#include "message_codec.h"

namespace net {

    static constexpr size_t DEFAULT_FRAME_SIZE = 4096;

    // 枚举：连接状态
    enum class ConnectionType {
        TCP,
        UDP,
        KCP,
    };

    // 枚举：连接状态
    enum class ConnectionState {
        Disconnected,
        Connecting,
        Connected,
        Closing
    };

    class Connection : public std::enable_shared_from_this<Connection> {
    public:
        using Ptr = std::shared_ptr<Connection>;
        using Buffer = std::vector<uint8_t>;

        // 回调函数类型定义
        using MessageHandler = std::function<void(Ptr, const Buffer&, size_t)>;
        using ErrorHandler = std::function<void(Ptr, const boost::system::error_code&)>;
        using StateChangeHandler = std::function<void(Ptr, ConnectionState)>;

        virtual ~Connection() = default;

        virtual void setCodec(std::unique_ptr<MessageCodec> codec) = 0;

        virtual void send(const Buffer& data) = 0;
        virtual void send(const std::string& data) = 0;
        virtual void send(const char* data, size_t length) = 0;

        virtual void setMessageReceiver(MessageHandler handler) = 0;
        virtual void setErrorHandler(ErrorHandler handler) = 0;
        virtual void setStateChangeHandler(StateChangeHandler handler) = 0;

        virtual ConnectionState getState() const = 0;

        virtual ConnectionType getType() const = 0;

        virtual void close() = 0;

        virtual void start() = 0;

    protected:
        std::unique_ptr<MessageCodec> m_codec;
        ConnectionState m_currentState = ConnectionState::Disconnected;
        MessageHandler m_messageHandler;
        StateChangeHandler m_stateChangeHandler;
        ErrorHandler m_errorHandler;

        // 辅助函数：更新状态并触发回调
        void updateState(ConnectionState newState) {
            if (m_currentState != newState) {
                m_currentState = newState;
                if (m_stateChangeHandler) {
                    m_stateChangeHandler(shared_from_this(), newState);
                }
            }
        }

    };

} // net
